{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "7731f647-8792-4242-80bf-29316cd49804", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Working on a Windows 10\n", "Python version 3.11.8 | packaged by conda-forge | (main, Feb 16 2024, 20:40:50) [MSC v.1937 64 bit (AMD64)]\n", "Pandas version 2.2.3\n", "bifacial_radiance version 0.5.0b2.dev4+gedb973d.d20250924\n" ] } ], "source": [ "# This information helps with debugging and getting support :)\n", "import sys, platform\n", "import pandas as pd\n", "import bifacial_radiance as br\n", "print(\"Working on a \", platform.system(), platform.release())\n", "print(\"Python version \", sys.version)\n", "print(\"Pandas version \", pd.__version__)\n", "print(\"bifacial_radiance version \", br.__version__)" ] }, { "cell_type": "markdown", "id": "d44f4591", "metadata": {}, "source": [ "# 15 - New Functionalities Examples\n", "\n", "This journal includes short examples on how to use the new functionalities of version 0.4.0 of bifacial_radiance. The parts are:\n", "\n", "1. Simulating Modules with Frames and Omegas \n", "2. Improvements to irradiance sampling\n", " * Scanning full module (sensors on x)!\n", " * Different points in the front and the back\n", "3. Full row scanning." ] }, { "cell_type": "code", "execution_count": 1, "id": "52d5ac54", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Your simulation will be stored in C:\\Users\\mprillim\\sam_dev\\bifacial_radiance\\bifacial_radiance\\TEMP\\Tutorial_15\n" ] } ], "source": [ "import bifacial_radiance\n", "\n", "import os\n", "from pathlib import Path\n", "\n", "testfolder = str(Path().resolve().parent.parent / 'bifacial_radiance' / 'TEMP' / 'Tutorial_15')\n", "if not os.path.exists(testfolder):\n", " os.makedirs(testfolder)\n", " \n", "print (\"Your simulation will be stored in %s\" % testfolder)\n" ] }, { "cell_type": "markdown", "id": "c8f30f6e", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "308fd255", "metadata": {}, "source": [ "## I. Simulating Frames and Omegas\n", "\n", "The values for generating frames and omegas are described in the makeModule function, which is where they are introduced into the basic module unit. This diagram shows how they are measured. " ] }, { "cell_type": "markdown", "id": "2c906cd6", "metadata": {}, "source": [ "\n", "![Folder Structure](../images_wiki/makeModule_ComplexGeometry.PNG)\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "6711cfc1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "path = C:\\Users\\mprillim\\sam_dev\\bifacial_radiance\\bifacial_radiance\\TEMP\\Tutorial_15\n", "Making path: images\n", "Making path: objects\n", "Making path: results\n", "Making path: skies\n", "Making path: EPWs\n", "Making path: materials\n", "\n", "Module Name: test-module\n", "Module test-module updated in module.json\n" ] } ], "source": [ "module_type = 'test-module'\n", "\n", "frameParams = {'frame_material' : 'Metal_Grey', \n", " 'frame_thickness' : 0.05,\n", " 'nSides_frame' : 4,\n", " 'frame_width' : 0.08}\n", "\n", "frameParams = {'frame_material' : 'Metal_Grey', \n", " 'frame_thickness' : 0.05,\n", " 'nSides_frame' : 4,\n", " 'frame_width' : 0.08}\n", "\n", "omegaParams = {'omega_material': 'litesoil',\n", " 'x_omega1' : 0.4,\n", " 'mod_overlap' : 0.25,\n", " 'y_omega' : 1.5,\n", " 'x_omega3' : 0.25,\n", " 'omega_thickness' : 0.05,\n", " 'inverted' : False}\n", "\n", "tubeParams = { 'visible': True,\n", " 'axisofrotation' : True,\n", " 'diameter' : 0.3\n", " }\n", "\n", "\n", "demo = bifacial_radiance.RadianceObj('tutorial_15', testfolder) \n", "\n", "mymodule = demo.makeModule(module_type,x=2, y=1, xgap = 0.02, ygap = 0.15, zgap = 0.3, \n", " numpanels = 2, tubeParams=tubeParams,\n", " frameParams=frameParams, omegaParams=omegaParams)\n" ] }, { "cell_type": "markdown", "id": "a9f1fb3d", "metadata": {}, "source": [ "Alternatively, the paremeters can be passed from an Object Oriented Approach as follows:" ] }, { "cell_type": "code", "execution_count": 3, "id": "380b09fe", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Module test-module updated in module.json\n", "Pre-existing .rad file objects\\test-module.rad will be overwritten\n", "\n", "Module test-module updated in module.json\n", "Pre-existing .rad file objects\\test-module.rad will be overwritten\n", "\n", "Module test-module updated in module.json\n", "Pre-existing .rad file objects\\test-module.rad will be overwritten\n", "\n" ] } ], "source": [ "mymodule.addTorquetube(visible = True, axisofrotation = True, diameter = 0.3)\n", "\n", "mymodule.addOmega(omega_material = 'litesoil', x_omega1 = 0.4, mod_overlap = 0.25,\n", " y_omega = 1.5, x_omega3 = 0.25, omega_thickness = 0.05, inverted = False)\n", "\n", "mymodule.addFrame(frame_material = 'Metal_Grey', frame_thickness = 0.05, nSides_frame = 4, frame_width = 0.08)\n", " " ] }, { "cell_type": "markdown", "id": "eb69d5d6", "metadata": {}, "source": [ "Let's add the rest of the scene and go until OCT, so it can be viewed with rvu:" ] }, { "cell_type": "code", "execution_count": 4, "id": "fc0fa941", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading albedo, 1 value(s), 0.200 avg\n", "1 nonzero albedo values.\n", "Getting weather file: USA_VA_Richmond.724010_TMY2.epw\n", " ... OK!\n", "8760 line in WeatherFile. Assuming this is a standard hourly WeatherFile for the year for purposes of saving Gencumulativesky temporary weather files in EPW folder.\n", "Coercing year to 2021\n", "Saving file EPWs\\metdata_temp.csv, # points: 8760\n", "Calculating Sun position for Metdata that is right-labeled with a delta of -30 mins. i.e. 12 is 11:30 sunpos\n", "Created tutorial_15.oct\n" ] }, { "data": { "text/plain": [ "'tutorial_15.oct'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "demo.setGround(0.2)\n", "epwfile = demo.getEPW(lat = 37.5, lon = -77.6)\n", "metdata = demo.readWeatherFile(epwfile, coerce_year = 2021)\n", "demo.gendaylit(4020)\n", "\n", "sceneDict = {'tilt':0, 'pitch':3, 'clearance_height':3,'azimuth':90, 'nMods': 1, 'nRows': 1} \n", "scene = demo.makeScene(mymodule,sceneDict)\n", "demo.makeOct()" ] }, { "cell_type": "markdown", "id": "13fdb933", "metadata": {}, "source": [ "To view the module from different angles, you can use the following rvu commands in your terminal:\n", "\n", " rvu -vp -7 0 3 -vd 1 0 0 Sim1.oct\n", "\n", "\n", " rvu -vp 0 -5 3 -vd 0 1 0 Sim1.oct" ] }, { "cell_type": "code", "execution_count": 5, "id": "2481ff66", "metadata": {}, "outputs": [], "source": [ "\n", "## Comment any of the ! line below to run rvu from the Jupyter notebook instead of your terminal.\n", "## Simulation will stop until you close the rvu window(s).\n", "\n", "#!rvu -vp -7 0 3 -vd 1 0 0 Sim1.oct\n", "#!rvu -vp 0 -5 3 -vd 0 1 0 Sim1.oct\n" ] }, { "cell_type": "markdown", "id": "0c4493eb", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "bd0a6e05", "metadata": {}, "source": [ "## II. Improvements to irradiance sampling\n" ] }, { "cell_type": "markdown", "id": "bd34faa1", "metadata": {}, "source": [ "The key ideas here are:\n", "\n", "- `moduleAnalysis()` returns two structured dictionaries that have the coordinates necessary for analysis to know where to smaple. On the new version, different values can be given for sampling accross the collector slope (y), for both front and backs by using a single value or an array in ``sensorsy``. \n", "\n", "- Furthermore, now scanning on the module's x-direction is supported, by setting the variables ``sensorsx`` as an singel value or an array.\n", "\n", "When the sensors differ between the front and the back, instead of saving one .csv with results, two .csv files are saved, one labeled \"_Front.csv\" and the other \"_Back.csv\".\n", "\n", "To know more, read the functions documentation.\n", "\n", "\n", "We'll take advantage of Simulation 1 testfolder, Radiance Objects and sky, but let's make a simple module and scene and model it through from there." ] }, { "cell_type": "code", "execution_count": 6, "id": "08291374", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Module Name: test-module\n", "Module test-module updated in module.json\n", "Pre-existing .rad file objects\\test-module.rad will be overwritten\n", "\n" ] } ], "source": [ "mymodule = demo.makeModule(name='test-module',x=2, y=1)\n", "sceneDict = {'tilt':0, 'pitch':6, 'clearance_height':3,'azimuth':180, 'nMods': 1, 'nRows': 1} " ] }, { "cell_type": "code", "execution_count": 7, "id": "3ec94898", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Created tutorial_15.oct\n" ] } ], "source": [ "scene = demo.makeScene(mymodule,sceneDict)\n", "octfile = demo.makeOct()\n", "analysis = bifacial_radiance.AnalysisObj() # return an analysis object including the scan dimensions for back irradiance" ] }, { "cell_type": "markdown", "id": "0ea6414f", "metadata": {}, "source": [ "### Same sensors front and back, two sensors accross x" ] }, { "cell_type": "code", "execution_count": 8, "id": "715ddc04", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Linescan in process: 2222_Front\n", "Linescan in process: 2222_Back\n", "Saved: results\\irr_2222.csv\n", "\n", "--> RESULTS for Front and Back are saved on the same file since the sensors match for front and back\n", "\n", " x y z rearZ mattype \\\n", "0 -0.333333 -0.166667 3.021 2.999 a0.0.a0.test-module.6457 \n", "1 -0.333333 0.166667 3.021 2.999 a0.0.a0.test-module.6457 \n", "2 0.333333 -0.166667 3.021 2.999 a0.0.a0.test-module.6457 \n", "3 0.333333 0.166667 3.021 2.999 a0.0.a0.test-module.6457 \n", "\n", " rearMat Wm2Front Wm2Back Back/FrontRatio \n", "0 a0.0.a0.test-module.2310 188.8667 36.90352 0.195393 \n", "1 a0.0.a0.test-module.2310 188.8637 36.89747 0.195365 \n", "2 a0.0.a0.test-module.2310 188.8633 36.89517 0.195353 \n", "3 a0.0.a0.test-module.2310 188.8603 36.88242 0.195288 \n" ] } ], "source": [ "name='2222'\n", "sensorsy_front = 2\n", "sensorsy_back = 2\n", "sensorsx_front = 2\n", "sensorsx_back = 2\n", "\n", "sensorsy = [sensorsy_front, sensorsy_back]\n", "sensorsx = [sensorsx_front, sensorsx_back]\n", "\n", "frontscan, backscan = analysis.moduleAnalysis(scene, sensorsy = sensorsy, sensorsx=sensorsx)\n", "\n", "frontDict, backDict = analysis.analysis(octfile = octfile, name = name, frontscan = frontscan, \n", " backscan = backscan)\n", "\n", "print('\\n--> RESULTS for Front and Back are saved on the same file since the sensors match for front and back')\n", "print('\\n', bifacial_radiance.load.read1Result('results\\irr_'+name+'_Row1_Module1.csv'))\n" ] }, { "cell_type": "markdown", "id": "687132bd", "metadata": {}, "source": [ "### Different sensors front and back, two sensors accross x" ] }, { "cell_type": "code", "execution_count": 11, "id": "771faf57", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Linescan in process: 2412_Row1_Module1_Front\n", "Linescan in process: 2412_Row1_Module1_Back\n", "Saved: results\\irr_2412_Row1_Module1_Front.csv\n", "Saved: results\\irr_2412_Row1_Module1_Back.csv\n", "\n", "--> RESULTS for Front and Back are saved on SEPARATE file since the sensors do not match for front and back\n", "\n", "FRONT\n", " x y z mattype Wm2Front\n", "0 0.0 -0.167 3.025 a0.0.a0.test-module.6457 187.685\n", "1 0.0 0.167 3.025 a0.0.a0.test-module.6457 187.682\n", "\n", "BACK\n", " x y z rearMat Wm2Back\n", "0 -0.333 -0.3 2.994 a0.0.a0.test-module.2310 36.644\n", "1 -0.333 -0.1 2.994 a0.0.a0.test-module.2310 36.632\n", "2 -0.333 0.1 2.994 a0.0.a0.test-module.2310 36.620\n", "3 -0.333 0.3 2.994 a0.0.a0.test-module.2310 36.608\n", "4 0.333 -0.3 2.994 a0.0.a0.test-module.2310 36.640\n", "5 0.333 -0.1 2.994 a0.0.a0.test-module.2310 36.618\n", "6 0.333 0.1 2.994 a0.0.a0.test-module.2310 36.605\n", "7 0.333 0.3 2.994 a0.0.a0.test-module.2310 36.591\n" ] } ], "source": [ "name='2412'\n", "\n", "sensorsy_front = 2\n", "sensorsy_back = 4\n", "\n", "sensorsx_front = 1\n", "sensorsx_back = 2\n", "\n", "sensorsy = [sensorsy_front, sensorsy_back]\n", "sensorsx = [sensorsx_front, sensorsx_back]\n", "\n", "frontscan, backscan = analysis.moduleAnalysis(scene, sensorsy=sensorsy, sensorsx=sensorsx)\n", "\n", "frontDict, backDict = analysis.analysis(octfile = octfile, name = name, frontscan = frontscan, \n", " backscan = backscan)\n", "\n", "print('\\n--> RESULTS for Front and Back are saved on SEPARATE file since the sensors do not match for front and back')\n", "\n", "print('\\nFRONT\\n', bifacial_radiance.load.read1Result('results\\irr_'+name+'_Row1_Module1_Front.csv'))\n", "print('\\nBACK\\n', bifacial_radiance.load.read1Result('results\\irr_'+name+'_Row1_Module1_Back.csv'))" ] }, { "cell_type": "markdown", "id": "f8d26acc", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "175a8b1d", "metadata": {}, "source": [ "## III. Making Analysis Function for Row\n", "\n", "\n", "Let's explore how to analyze easily a row with the new function `analyzeRow`. As before, we are not repeating functions alreayd called above, just re-running the necessary ones to show the changes. " ] }, { "cell_type": "code", "execution_count": 12, "id": "d6ad80ab", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Append=False in makeScene. Existing scenes being over-written. \n", "Created tutorial_15.oct\n" ] } ], "source": [ "sceneDict = {'tilt':0, 'pitch':30, 'clearance_height':3,'azimuth':90, 'nMods': 3, 'nRows': 3} \n", "scene = demo.makeScene(mymodule,sceneDict)\n", "octfile = demo.makeOct()" ] }, { "cell_type": "markdown", "id": "5b4861a7", "metadata": {}, "source": [ "The function requires to know the number of modules on the row" ] }, { "cell_type": "code", "execution_count": 13, "id": "003a07c3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Linescan in process: 2412_Row1_Module1_Front\n", "Linescan in process: 2412_Row1_Module1_Back\n", "Saved: results\\irr_2412_Row1_Module1.csv\n", "Linescan in process: 2412_Row1_Module2_Front\n", "Linescan in process: 2412_Row1_Module2_Back\n", "Saved: results\\irr_2412_Row1_Module2.csv\n", "Linescan in process: 2412_Row1_Module3_Front\n", "Linescan in process: 2412_Row1_Module3_Back\n", "Saved: results\\irr_2412_Row1_Module3.csv\n", "Making path for compiled results: results\\CompiledResults\n" ] } ], "source": [ "sensorsy_back=1 \n", "sensorsx_back=1 \n", "sensorsy_front=1\n", "sensorsx_front=1\n", "\n", "sensorsy = [sensorsy_front, sensorsy_back]\n", "sensorsx = [sensorsx_front, sensorsx_back]\n", "\n", "rowscan = analysis.analyzeRow(name = name, scene = scene, sensorsy=sensorsy, sensorsx = sensorsx,\n", " rowWanted = 1, octfile = octfile)" ] }, { "cell_type": "markdown", "id": "9569d5ad", "metadata": {}, "source": [ "``rowscan`` is now a dataframe containing the values of each module in the row. Check the x, y and " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.8" } }, "nbformat": 4, "nbformat_minor": 5 }